package com.shiro.demo.realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

/**
 * @author zhubayi
 */
public class CustomerRealm extends AuthorizingRealm {
    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //拿到主体
        String primaryPrincipal =(String) principalCollection.getPrimaryPrincipal();
        System.out.println("primaryPrincipal="+primaryPrincipal);
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addRole("admin");
        //修改用户的权限
        simpleAuthorizationInfo.addStringPermission("user:update:*");
        simpleAuthorizationInfo.addStringPermission("product:*:*");

        return simpleAuthorizationInfo;
    }

    /**
     * 认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String principal =(String) authenticationToken.getPrincipal();
        if("zhubayi".equals(principal)){
            String password = "3c88b338102c1a343bcb88cd3878758e";
            String salt = "Q4F%";
            return new SimpleAuthenticationInfo(principal,password,
                    ByteSource.Util.bytes(salt),this.getName());
            /**
             * 第一个参数，有的人传的是userInfo对象对用的用户名。在学习过程中，传入的都是user对象，没有尝试过对象对应的用户名，但是从前辈们的经验看得到，此处也可以传用户名，因人而异吧。
             *
             * 第二个参数，传的是从数据库中获取的password，然后再与token中的password进行对比，匹配上了就通过，匹配不上就报异常。
             *
             * 第三个参数，盐–用于加密密码对比，–获取的经验：为了防止两用户的初始密码是一样的，
             * –巨佬们的解答：四个参数，防止两用户可能初始密码相同时候用，token 用simplehash（四个参数的构造） 加密默认用了MD5 迭代一次加密，info中在密码比对调用new SimpleHash(String algorithmName, Object source）这个实例化对象默认迭代一次了，所以当你用三个参数加密时候可能两 个初始密码相同人的就没能区别开 （因此realm中密码要从数据库的查的原因），通过设置reaml 中credentialsMatcher 属性的各项属性可实现
             *
             * 第四个参数：当前realm的名字。
             *
             * 第一个参数可以直接通过token.getPrincipal()方法获取—获取当前记录的用户名，从这个用户名获取一系列的对应需求属性。
             */
        }
        return null;
    }
}
